/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.core.services.impl;

import java.io.Serializable;
import java.util.List;

import org.libermundi.theorcs.core.dao.GenericDao;
import org.libermundi.theorcs.core.model.base.Identifiable;
import org.libermundi.theorcs.core.services.Manager;
import org.libermundi.theorcs.core.util.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Abstract Manager Service
 * Implements an set of utility methods used by all manager
 *
 */
@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRED)
public abstract class AbstractManagerImpl<T extends Identifiable<I>,I extends Serializable> implements Manager<T,I> {
	private static final Logger logger = LoggerFactory.getLogger(AbstractManagerImpl.class);
	
	protected GenericDao<T,I> _dao;
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#getDao()
	 */
	@Override
	public GenericDao<T,I> getDao() {
		return _dao;
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#setDao(org.libermundi.theorcs.core.dao.GenericDao)
	 */
	@Override
	public void setDao(GenericDao<T,I> dao) {
		logger.debug("Set DAO : " + dao);
		this._dao = dao;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#delete(java.io.Serializable)
	 */
	@Override
	public void delete(I id) {
		if(logger.isDebugEnabled()) {
			logger.debug("Delete Object with ID : " + id);
		}
		_dao.delete(id);
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#delete(org.libermundi.theorcs.core.model.base.Identifiable)
	 */
	@Override
	public void delete(T object) {
		_dao.delete(object);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#getAll()
	 */
	@Override
	public List<T> getAll() {
		return _dao.getAll();
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#refresh(org.libermundi.theorcs.core.model.base.Identifiable)
	 */
	@Override
	public void refresh(T obj) {
		_dao.refresh(obj);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#load(java.io.Serializable)
	 */
	@Override
	public T load(I id) {
		return _dao.load(id);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#save(org.libermundi.theorcs.core.model.base.Identifiable)
	 */
	@Override
	public void save(T entity) {
		_dao.save(entity);
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#save(T[])
	 */
	@Override
	@SuppressWarnings("unchecked")
	public void save(T... entities) {
		_dao.save(entities);
	}
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#duplicate(org.libermundi.theorcs.core.model.base.Identifiable)
	 */
	@Override
	public T duplicate(T original) {
		return duplicate(original, Boolean.TRUE);
	}
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#duplicate(org.libermundi.theorcs.core.model.base.Identifiable, boolean)
	 */
	@Override
	public T duplicate(T original, boolean resetPrimaryKey) {
		T copy = ObjectUtils.safeDeepCopy(original);
		if(resetPrimaryKey){
			copy.setId(null);
		}
		return copy;
	}
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#getAllCount()
	 */
	@Override
	public Long getAllCount() {
		if(logger.isDebugEnabled()) {
			logger.debug(" Execute : getAllCount() for entity " + _dao.getEntityClass().getName());
		}
		return Long.valueOf(_dao.countAll());
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#flush()
	 */
	@Override
	public void flush() {
		if(logger.isDebugEnabled()) {
			logger.debug(" Execute : flush()");
		}
		_dao.flush();
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#loadLast()
	 */
	@Override
	public T loadLast() {
		if(logger.isDebugEnabled()) {
			logger.debug(" Execute : loadLast())");
		}
		return _dao.loadLast();
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.Manager#initDao()
	 */
	@Override
	public void initialize() {}
}
